﻿using System;
using System.Windows.Forms;
using System.Net;
using System.Diagnostics;
using System.ComponentModel;
using System.Reflection;
using System.Threading;
using CodePlexLegerisDownload.Properties;
using Microsoft.Win32;


namespace CodePlexLegerisDownload
{
    public partial class Form1 : Form
    {
        private SaveFileDialog _saveFileDialog1 = new SaveFileDialog();
        private static readonly string ProgramName = Assembly.GetExecutingAssembly().CodeBase.Substring(Assembly.GetExecutingAssembly().CodeBase.LastIndexOf(@"/", StringComparison.Ordinal)+1);
        private const string SzRegPath = @"SOFTWARE\SPAdditions\DownloadExe\1.0\";

        private string regEmailAddress;

#if DEBUG
        private string _url = $"http://localhost:62659/download.ashx?{{0}}=3B51672E-AA11-4C3A-9609-6228264E101A7{ProgramName}";
#else
        private string _url = $"http://legerispid.azurewebsites.net/download.ashx?{{0}}=3B51672E-AA11-4C3A-9609-6228264E101A7{ProgramName}";
#endif

        public Form1()
        {
            Load += Form_Load;

            InitializeComponent();

            StartPosition = FormStartPosition.CenterScreen;

            GetRegistryValues();

            tbEmail1.Focus();

            if (!string.IsNullOrEmpty(regEmailAddress)) tbEmail2.Text = tbEmail1.Text = regEmailAddress;
        }

        private void Form_Load(object sender, EventArgs e)
        {
            // Check we have internet access...
            try
            {
                WebClient webClient = new WebClient();
                webClient.OpenRead(string.Format(_url, "Alive"));
            }
            catch (Exception ex)
            {
                MessageBox.Show($"Please check your internet connection: {ex.Message}", @"Legeris for SharePoint Downloader", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
                Close();
            }
        }

        private void btnDownload_Click(object sender, EventArgs e)
        {
            cbExtract.Enabled = btnDownload.Enabled = false;
            if (tbEmail1.Text.Length > 0)
                _url += $"&email={tbEmail1.Text}";

            // ReSharper disable once LocalizableElement
            lblStatus.Text = "Waiting for file save location to be chosen...";

            _saveFileDialog1 = new SaveFileDialog
            {
                FileName = "Legeris.Distribution.exe",
                RestoreDirectory = true
            };

            if (_saveFileDialog1.ShowDialog() == DialogResult.OK)
            {
                try
                {
                    WebClient webClient = new WebClient();
                    webClient.DownloadFileCompleted += new AsyncCompletedEventHandler(DownloadFileCallback2);

                    webClient.DownloadProgressChanged += (s, ee) =>
                    {
                        // ReSharper disable once LocalizableElement
                        lblStatus.Text = "Downloading...";
                        progressBar.Value = ee.ProgressPercentage;
                    };

                    // ReSharper disable once LocalizableElement
                    lblStatus.Text = "Waiting for download to start...";
                    Application.DoEvents();

                    webClient.DownloadFileAsync(new Uri(string.Format(_url, "OrgId")), _saveFileDialog1.FileName);
                }
                catch (Exception ex)
                {
                    // ReSharper disable once LocalizableElement
                    MessageBox.Show(ex.Message, "Legeris for SharePoint download error", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
                    Application.Exit();
                }
            }
        }

        private void DownloadFileCallback2(object sender, AsyncCompletedEventArgs e)
        {
            
            lblStatus.Text = "Verifying download status..."; 
            Application.DoEvents();

            // Check e for status of email address verification 
            if (e.Error != null)
            {
                var wes = (WebException) e.Error; 

                if (wes.Response.Headers["PIDService-SNOError"] != null)
                {
                    MessageBox.Show($"We're sorry but an unexpected error '{wes.Response.Headers["PIDService-SNOError"]}' has occurred, our support team have been notified and will contact you by email shortly. For all support issues you can contact us via email at: support@legeris.zendesk.com", Resources.Form1_DownloadFileCallback2_Legeris_for_SharePoint, MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
                    lblStatus.Text = $"Error: {wes.Response.Headers["PIDService-Error"]}";
                    Application.DoEvents();
                    Thread.Sleep(3000);
                    Application.Exit();
                }
                else if (wes.Response.Headers["PIDService-OptInMessage"] != null)
                {
                    var hdrText = wes.Response.Headers["PIDService-OptInMessage"];
                    // ReSharper disable LocalizableElement
                    MessageBox.Show($"{hdrText}" + 
                        "\r\n" +
                        "\r\n" +
                        "Please check your Inbox for an email from Legeris Support (support@legeris.zendesk.com) as you need to follow its instructions to complete email address verification. " + 
                        "Once verified you will receive a second email containing the license key required to active Legeris. " +
                        "\r\n" +
                        "\r\n" +
                        "Legeris can be downloaded by running this program again following email address verification or from the link in the second email. " + 
                        "\r\n" +
                        "\r\n" +
                        "If you have not received the email within 15 minutes please check your Junk/Clutter email folders. If you still can't find it please email us at support@legeris.zendesk.com.", 
                        Resources.Form1_DownloadFileCallback2_Legeris_for_SharePoint, MessageBoxButtons.OK, MessageBoxIcon.Information);
                    lblStatus.Text = "Check your email and verify your email address... exiting in 4s";
                    // ReSharper restore LocalizableElement
                    Application.DoEvents();
                    Thread.Sleep(4000);
                    Application.Exit();
                }
                else
                {
                    MessageBox.Show($"We're sorry but an unknown error has occurred, our support team have been notified and will contact you by email shortly. For all support issues you can contact us via email at: support@legeris.zendesk.com", Resources.Form1_DownloadFileCallback2_Legeris_for_SharePoint, MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
                    //lblStatus.Text = $"Error: {wes.Response.}";
                    Application.DoEvents();
                    Thread.Sleep(3000);
                    Application.Exit();
                }
                
                return;
            }

            if (cbExtract.Checked)
            {
                // ReSharper disable once LocalizableElement
                lblStatus.Text = "Launching Legeris installation media extraction...";
                Application.DoEvents();

                using (Process proc = Process.Start(_saveFileDialog1.FileName))
                {
                    proc.WaitForExit();
                    Application.Exit();
                }
            }
            
            lblStatus.Text = @"Closing in 3s...";
            Application.DoEvents();

            Thread.Sleep(3000);
            Application.Exit();
        }

        private void Form1_Load(object sender, EventArgs e)
        {

        }

        private void textBox1_TextChanged(object sender, EventArgs e)
        {
            errorProvider1.Clear();

            if (tbEmail1.Text.Length == 0)
            {
                lbltbemail2.Enabled = tbEmail2.Enabled = false;
                SetRegistrySetting("email","");
                return;
            }

            try
            {
                if (tbEmail1.Text.LastIndexOf(".", StringComparison.Ordinal) < 0 ||
                    tbEmail1.Text.Length < tbEmail1.Text.LastIndexOf(".", StringComparison.Ordinal) + 2|| 
                    tbEmail1.Text.IndexOf("@", StringComparison.Ordinal) < 0 
                    )
                {
                    errorProvider1.SetError((TextBox) sender, "Invalid email address");
                    cbExtract.Enabled = btnDownload.Enabled = false;
                    tbEmail2.Text = "";
                    lbltbemail2.Enabled = tbEmail2.Enabled = false;
                    errorProvider1.SetError(tbEmail2, "");

                    if (string.IsNullOrEmpty(regEmailAddress)) return;

                    regEmailAddress = "";
                    SetRegistrySetting("email", regEmailAddress);
                }
                else
                {
                    lbltbemail2.Enabled = tbEmail2.Enabled = true;
                    tbEmail2.Text = "";
                }
            }
            catch (ArgumentException)
            {
                //textBox is empty
            }
            catch (FormatException)
            {
                //textBox contains no valid mail address
                errorProvider1.SetError((TextBox)sender, "Invalid email address");
            }
        }

        private void tbEmail2_TextChanged(object sender, EventArgs e)
        {
            errorProvider1.SetError((TextBox) sender, "Email address doesn't match");

            if (tbEmail2.Text.Length == 0)
            {
                cbExtract.Enabled = btnDownload.Enabled = false;
                return;
            }

            if (!tbEmail1.Text.Equals(tbEmail2.Text, StringComparison.CurrentCultureIgnoreCase))
            {
                cbExtract.Enabled = btnDownload.Enabled = false;

                if (string.IsNullOrEmpty(regEmailAddress)) return;

                regEmailAddress = "";
                SetRegistrySetting("email", regEmailAddress);
                return;
            }

            errorProvider1.Clear();
            cbExtract.Enabled = btnDownload.Enabled = true;
            SetRegistrySetting("email", tbEmail2.Text);
        }


        public void GetRegistryValues()
        {
            try
            {
                RegistryKey myReg = Registry.CurrentUser.OpenSubKey(SzRegPath);

                // Initialise on fist use
                if (myReg == null)
                {
                    myReg = Registry.CurrentUser.CreateSubKey(SzRegPath);
                    myReg.SetValue("email", "");
                }

                // Now read them back

                regEmailAddress = (string)myReg.GetValue("email", "");
                myReg.Close();
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.ToString(), $"STOP Cannot access registry: {SzRegPath}", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }

        public void SetRegistrySetting(string settingName, string settingValue)
        {
            try
            {
                RegistryKey myReg = Registry.CurrentUser.OpenSubKey(SzRegPath, true) ?? Registry.CurrentUser.CreateSubKey(SzRegPath);
                myReg.SetValue(settingName, settingValue);
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.ToString(), $"STOP Cannot access registry: {SzRegPath}", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }
    }
}
